<!DOCTYPE HTML>
<html lang="en">
<head>
<title>InputHook() - Syntax &amp; Usage | AutoHotkey</title>
<meta name="description" content="The InputHook function creates an object which can be used to collect or intercept keyboard input." />
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<link href="../static/theme.css" rel="stylesheet" type="text/css" />
<script src="../static/content.js" type="text/javascript"></script>
</head>
<body>

<h1>InputHook() <span class="ver">[v1.1.31+]</span></h1>

<p>Creates an object which can be used to collect or intercept keyboard input.</p>

<pre class="Syntax">InputHook := <span class="func">InputHook</span>(<span class="optional">Options, EndKeys, MatchList</span>)</pre>
<h2>Parameters</h2>
<dl>

  <dt>Options</dt>
  <dd>
    <p><u>A string of zero or more of the following letters (in any order, with optional spaces in between):</u></p>
    <p id="option-b"><strong>B</strong>: Sets <a href="#BackspaceIsUndo">BackspaceIsUndo</a> to false, which causes <kbd>Backspace</kbd> to be ignored.</p>
    <p id="option-c"><strong>C</strong>: Sets <a href="#CaseSensitive">CaseSensitive</a> to true, making <em>MatchList</em> case sensitive.</p>
    <p id="option-i"><strong>I</strong>: Sets <a href="#MinSendLevel">MinSendLevel</a> to 1 or a given value, causing any input with <a href="SendLevel.htm">send level</a> below this value to be ignored. For example, <code>I2</code> would ignore any input with a level of 0 (the default) or 1, but would capture input at level 2.</p>
    <p id="option-l"><strong>L</strong>: Length limit (e.g. <code>L5</code>). The maximum allowed length of the input. When the text reaches this length, the Input is terminated and EndReason is set to the word Max (unless the text matches one of the <em>MatchList</em> phrases, in which case EndReason is set to the word Match). If unspecified, the length limit is 1023.</p>
    <p>Specifying <code>L0</code> disables collection of text and the length limit, but does not affect which keys are counted as producing text (see <a href="#VisibleText">VisibleText</a>). This can be useful in combination with <a href="#OnChar">OnChar</a>, <a href="#OnKeyDown">OnKeyDown</a>, <a href="#KeyOpt">KeyOpt</a> or <em><a href="#EndKeys">EndKeys</a></em>.</p>
    <p id="option-m"><strong>M</strong>: Modified keystrokes such as <kbd>Control</kbd>+<kbd>A</kbd> through <kbd>Control</kbd>+<kbd>Z</kbd> are recognized and transcribed if they correspond to real ASCII characters. Consider this example, which recognizes <kbd>Control</kbd>+<kbd>C</kbd>:</p>
    <pre>CtrlC := Chr(3) <em>; Store the character for Ctrl-C in the CtrlC var.</em>
ih := InputHook("L1 M")
ih.Start()
ih.Wait()
if (ih.Input = CtrlC)
    MsgBox, You pressed Control-C.</pre>
    <p class="note"><strong>Note</strong>: The characters <kbd>Ctrl</kbd>+<kbd>A</kbd> through <kbd>Ctrl</kbd>+<kbd>Z</kbd> correspond to <a href="Chr.htm">Chr(1)</a> through <a href="Chr.htm">Chr(26)</a>. Also, the <strong>M</strong> option might cause some keyboard shortcuts such as <kbd>Ctrl</kbd>+<kbd>&larr;</kbd> to misbehave while an Input is in progress.</p>
    <p id="option-t"><strong>T</strong>: Sets <a href="#Timeout">Timeout</a> (e.g. <code>T3</code> or <code>T2.5</code>).</p>
    <p id="vis"><strong>V</strong>: Sets <a href="#VisibleText">VisibleText</a> and <a href="#VisibleNonText">VisibleNonText</a> to true. Normally, the user's input is blocked (hidden from the system). Use this option to have the user's keystrokes sent to the active window.</p>
    <p id="asterisk"><strong>*</strong>: Wildcard. Sets <a href="#FindAnywhere">FindAnywhere</a> to true, allowing matches to be found anywhere within what the user types.</p>
    <p id="E"><strong>E</strong>: Handle single-character end keys by character code instead of by keycode. This provides more consistent results if the active window's keyboard layout is different to the script's keyboard layout. It also prevents key combinations which don't actually produce the given end characters from ending input; for example, if <code>@</code> is an end key, on the US layout <kbd>Shift</kbd>+<kbd>2</kbd> will trigger it but <kbd>Ctrl</kbd>+<kbd>Shift</kbd>+<kbd>2</kbd> will not (if the E option is used). If the <strong>C</strong> option is also used, the end character is case-sensitive.</p>
  </dd>

  <dt id="EndKeys">EndKeys</dt>
  <dd>
    <p>A list of zero or more keys, any one of which terminates the Input when pressed (the end key itself is not written to the Input buffer). When an Input is terminated this way, EndReason is set to the word EndKey and the <a href="#EndKey">EndKey</a> property is set to the name of the key.</p>
    <p>The <em>EndKeys</em> list uses a format similar to the <a href="Send.htm">Send</a> command. For example, specifying <code>{Enter}.{Esc}</code> would cause either <kbd>Enter</kbd>, <kbd>.</kbd>, or <kbd>Escape</kbd> to terminate the Input. To use the braces themselves as end keys, specify <code>{{}</code> and/or <code>{}}</code>.</p>
    <p>To use <kbd>Control</kbd>, <kbd>Alt</kbd>, or <kbd>Shift</kbd> as end-keys, specify the left and/or right version of the key, not the neutral version. For example, specify <code>{LControl}{RControl}</code> rather than <code>{Control}</code>.</p>
    <p>Although modified keys such as <kbd>Alt</kbd>+<kbd>C</kbd> (!c) are not supported, non-alphanumeric characters such as <code>?!:@&amp;{}</code> by default require the Shift key to be pressed or not pressed depending on how the character is normally typed. If the <strong>E</strong> option is present, single character key names are interpreted as characters instead, and in those cases the modifier keys must be in the correct state to produce that character. When the <strong>E</strong> and <strong>M</strong> options are both used, <kbd>Control</kbd>+<kbd>A</kbd> through <kbd>Control</kbd>+<kbd>Z</kbd> are supported by including the corresponding ASCII control characters in <em>EndKeys</em>.</p>
    <p>An explicit key code such as <code>{vkFF}</code> or <code>{sc001}</code> may also be specified. This is useful in the rare case where a key has no name and produces no visible character when pressed. Its virtual key code can be determined by following the steps at the bottom fo the <a href="../KeyList.htm#SpecialKeys">key list page</a>.</p>
  </dd>

  <dt id="MatchList">MatchList</dt>
  <dd>
    <p>A comma-separated list of key phrases, any of which will cause the Input to be terminated (in which case EndReason will be set to the word Match). The entirety of what the user types must exactly match one of the phrases for a match to occur (unless the <a href="#asterisk">* option</a> is present). In addition, <strong>any spaces or tabs around the delimiting commas are significant</strong>, meaning that they are part of the match string. For example, if <em>MatchList</em> is <code>ABC , XYZ</code>, the user must type a space after ABC or before XYZ to cause a match.</p>
    <p>Two consecutive commas results in a single literal comma. For example, the following would produce a single literal comma at the end of string: <code>string1,,,string2</code>. Similarly, the following list contains only a single item with a literal comma inside it: <code>single,,item</code>.</p>
    <p>Because the items in <em>MatchList</em> are not treated as individual parameters, the list can be contained entirely within a variable. In fact, all or part of it must be contained in a variable if its length exceeds 16383 since that is the maximum length of any script line. For example, <em>MatchList</em> might consist of <code>%List1%,%List2%,%List3%</code> -- where each of the variables  contains a large sub-list of match phrases.</p>
  </dd>

</dl>

<h2 id="stack">Input Stack</h2>
<p>Any number of InputHook objects can be created and in progress at any time, but the order in which they are started affects how input is collected.</p>
<p>When each Input is started (by the <a href="#Start">Start</a> method or <a href="Input.htm">Input</a> command), it is pushed onto the top of a stack, and is removed from this stack only when the Input is terminated. Keyboard events are passed to each Input in order of most recently started to least. If an Input suppresses a given keyboard event, it is passed no further down the stack.</p>
<p><a href="Send.htm">Sent</a> keystrokes are ignored if the <a href="SendLevel.htm">send level</a> of the keystroke is below the InputHook's <a href="#MinSendLevel">MinSendLevel</a>. In such cases, the keystroke may still be processed by an Input lower on the stack.</p>
<p>Multiple InputHooks can be used in combination with <a href="#MinSendLevel">MinSendLevel</a> to separately collect both sent keystrokes and real ones.</p>
<p>Calling the <a href="Input.htm">Input</a> command terminates any previous Input started by the Input command, but leaves any InputHooks active. If the Input is not <a href="Input.htm#vis">visible</a>, any InputHooks which it interrupts will generally not collect any input until the Input command returns.</p>

<h2 id="object">InputHook Object</h2>
<p>The InputHook function returns an InputHook object, which has the following methods and properties.</p>
<p>Methods:</p>
<ul>
  <li><a href="#KeyOpt">KeyOpt</a>: Sets options for a key or list of keys.</li>
  <li><a href="#Start">Start</a>: Starts collecting input.</li>
  <li><a href="#Stop">Stop</a>: Terminates the Input and sets EndReason to the word Stopped.</li>
  <li><a href="#Wait">Wait</a>: Waits until the Input is terminated (InProgress is false).</li>
</ul>
<p>General Properties:</p>
<ul>
  <li><a href="#EndKey">EndKey</a>: Returns the name of the <a href="#EndKeys">end key</a> which was pressed to terminate the Input.</li>
  <li><a href="#EndMods">EndMods</a>: Returns a string of the modifiers which were logically down when Input was terminated.</li>
  <li><a href="#EndReason">EndReason</a>: Returns an <a href="#EndReasons">EndReason string</a> indicating how Input was terminated.</li>
  <li><a href="#InProgress">InProgress</a>: Returns true if the Input is in progress and false otherwise.</li>
  <li><a href="#Input">Input</a>: Returns any text collected since the last time Input was started.</li>
  <li><a href="#Match">Match</a>: Returns the <em>MatchList</em> item which caused the Input to terminate.</li>
  <li><a href="#OnEnd">OnEnd</a>: Retrieves or sets the <a href="../objects/Functor.htm">function object</a> which is called when Input is terminated.</li>
  <li><a href="#OnChar">OnChar</a>: Retrieves or sets the <a href="../objects/Functor.htm">function object</a> which is called after a character is added to the input buffer.</li>
  <li><a href="#OnKeyDown">OnKeyDown</a>: Retrieves or sets the <a href="../objects/Functor.htm">function object</a> which is called when a notification-enabled key is pressed.</li>
  <li><a href="#OnKeyUp">OnKeyUp</a>: Retrieves or sets the <a href="../objects/Functor.htm">function object</a> which is called when a notification-enabled key is released.</li>
</ul>
<p>Option Properties:</p>
<ul>
  <li><a href="#BackspaceIsUndo">BackspaceIsUndo</a>: Controls whether <kbd>Backspace</kbd> removes the most recently pressed character from the end of the Input buffer.</li>
  <li><a href="#CaseSensitive">CaseSensitive</a>: Controls whether <em>MatchList</em> is case sensitive.</li>
  <li><a href="#FindAnywhere">FindAnywhere</a>: Controls whether each match can be a substring of the input text.</li>
  <li><a href="#MinSendLevel">MinSendLevel</a>: Retrieves or sets the minimum <a href="SendLevel.htm">send level</a> of input to collect.</li>
  <li><a href="#NotifyNonText">NotifyNonText</a>: Controls whether the <a href="#OnKeyDown">OnKeyDown</a> and <a href="#OnKeyUp">OnKeyUp</a> callbacks are called whenever a non-text key is pressed.</li>
  <li><a href="#Timeout">Timeout</a>: Retrieves or sets the timeout value in seconds.</li>
  <li><a href="#VisibleNonText">VisibleNonText</a>: Controls whether keys or key combinations which do not produce text are visible (not blocked).</li>
  <li><a href="#VisibleText">VisibleText</a>: Controls whether keys or key combinations which produce text are visible (not blocked).</li>
</ul>

<div class="methodShort" id="KeyOpt"><h2>KeyOpt</h2>
<p>Sets options for a key or list of keys.</p>
<pre class="Syntax">InputHook.<span class="func">KeyOpt</span>(Keys, KeyOptions)</pre>
<dl>
  <dt>Keys</dt>
  <dd><p>A list of keys. Braces are used to enclose key names, virtual key codes or scan codes, similar to the <a href="Send.htm">Send</a> command. For example, <code>{Enter}.{{}</code> would apply to the <kbd>Enter</kbd>, <kbd>.</kbd> and <kbd>{</kbd> keys. Specifying a key by name, by <code>{vkNN}</code> or by <code>{scNNN}</code> may produce three different results; see below for details.</p>
  <p id="all-keys">Specify the string <code>{All}</code> (case-insensitive) on its own to apply <em>KeyOptions</em> to all VK and all SC. KeyOpt may then be called a second time to remove options from specific keys.</p></dd>
  <dt>KeyOptions</dt>
  <dd><p>One or more of the following single-character options (spaces and tabs are ignored).</p>
  <p id="KeyOpt-minus"><strong>-</strong> (minus): Removes any of the options following the <code>-</code>, up to the next <code>+</code>.</p>
  <p id="KeyOpt-plus"><strong>+</strong> (plus): Cancels any previous <code>-</code>, otherwise has no effect.</p>
  <p id="KeyOpt-e"><strong>E</strong>: End key. If enabled, pressing the key terminates Input, sets <a href="#EndReason">EndReason</a> to the word EndKey and the <a href="#EndKey">EndKey</a> property to the key's normalized name. Unlike the <em>EndKeys</em> parameter, the state of the Shift key is ignored. For example, <code>@</code> and <code>2</code> are both equivalent to <code>{vk32}</code> on the US keyboard layout.</p>
  <p id="KeyOpt-i"><strong>I</strong>: Ignore text. Any text normally produced by this key is ignored, and the key is treated as a non-text key (see <a href="#VisibleNonText">VisibleNonText</a>). Has no effect if the key normally does not produce text.</p>
  <p id="KeyOpt-n"><strong>N</strong>: Notify. Causes the <a href="#OnKeyDown">OnKeyDown</a> and <a href="#OnKeyUp">OnKeyUp</a> callbacks to be called each time the key is pressed.</p>
  <p id="KeyOpt-s"><strong>S</strong>: Suppresses (blocks) the key after processing it. This overrides <a href="#VisibleText">VisibleText</a> or <a href="#VisibleNonText">VisibleNonText</a> until <code>-S</code> is used. <code>+S</code> implies <code>-V</code>.</p>
  <p id="KeyOpt-v"><strong>V</strong>: Visible. Prevents the key from being suppressed (blocked). This overrides <a href="#VisibleText">VisibleText</a> or <a href="#VisibleNonText">VisibleNonText</a> until <code>-V</code> is used. <code>+V</code> implies <code>-S</code>.</p>
  </dd>
</dl>
<p id="KeyOpt-remarks">Options can be set by both virtual key code and scan code, and are accumulative.</p>
<p>When a key is specified by name, the options are set either by VK or by SC. Where two physical keys share the same VK but differ by SC (such as <kbd>Up</kbd> and <kbd>NumpadUp</kbd>), they are handled by SC. By contrast, if a VK number is used, it will apply to any physical key which produces that VK (and this may vary over time as it depends on the active keyboard layout).</p>
<p>Removing an option by VK number does not affect any options that were set by SC, or vice versa. However, when an option is removed by key name and that name is handled by VK, the option is also removed for the corresponding SC (according to the script's keyboard layout). This allows keys to be excluded by name after applying an option to <a href="#all-keys">all keys</a>.</p>
<p>If <code>+V</code> is set by VK and <code>+S</code> is set by SC (or vice versa), <code>+V</code> takes precedence.</p>
</div>

<div class="methodShort" id="Start"><h2>Start</h2>
<p>Starts collecting input.</p>
<pre class="Syntax">InputHook.<span class="func">Start</span>()</pre>
<p>Has no effect if the Input is already in progress.</p>
<p>The newly started Input is placed on the top of the <a href="#stack">InputHook stack</a>, which allows it to override any previously started Input.</p>
<p>This method installs the <a href="_InstallKeybdHook.htm">keyboard hook</a> (if it was not already).</p>
</div>

<div class="methodShort" id="Wait"><h2>Wait</h2>
<p>Waits until the Input is terminated (<a href="#InProgress">InProgress</a> is false).</p>
<pre class="Syntax">InputHook.<span class="func">Wait</span>(<span class="optional">MaxTime</span>)</pre>
<dl>
  <dt>MaxTime</dt>
  <dd><p>The maximum number of seconds to wait. If Input is still in progress after <em>MaxTime</em> seconds, the method returns and does not terminate Input.</p></dd>
</dl>
<p><strong>Returns</strong> <a href="#EndReason">EndReason</a>.</p>
</div>

<div class="methodShort" id="Stop"><h2>Stop</h2>
<p>Terminates the Input and sets <a href="#EndReason">EndReason</a> to the word Stopped.</p>
<pre class="Syntax">InputHook.<span class="func">Stop</span>()</pre>
<p>Has no effect if the Input is not in progress.</p>
</div>

<div class="methodShort" id="EndKey"><h2>EndKey</h2>
<p>Returns the name of the <a href="#EndKeys">end key</a> which was pressed to terminate the Input.</p>
<pre class="Syntax">KeyName := InputHook.EndKey</pre>
<p>Note that EndKey returns the "normalized" name of the key regardless of how it was written in <em>EndKeys</em>. For example, <code>{Esc}</code> and <code>{vk1B}</code> both produce <code>Escape</code>. <a href="GetKey.htm">GetKeyName()</a> can be used to retrieve the normalized name.</p>
<p>If the <a href="#E">E option</a> was used, EndKey returns the actual character which was typed (if applicable). Otherwise, the key name is determined according to the script's active keyboard layout.</p>
<p>EndKey returns an empty string if <a href="#EndReason">EndReason</a> is not "EndKey".</p>
</div>

<div class="methodShort" id="EndMods"><h2>EndMods</h2>
<p>Returns a string of the modifiers which were logically down when Input was terminated.</p>
<pre class="Syntax">Mods := InputHook.EndMods</pre>
<p>If all modifiers were logically down (pressed), the full string is:</p>
<pre>&lt;^&gt;^&lt;!&gt;!&lt;+&gt;+&lt;#&gt;#</pre>
<p>These modifiers have the same meaning as with <a href="../Hotkeys.htm">hotkeys</a>. Each modifier is always qualified with &lt; (left) or &gt; (right). The corresponding key names are: LCtrl, RCtrl, LAlt, RAlt, LShift, RShift, LWin, RWin.</p>
<p><a href="InStr.htm">InStr()</a> can be used to check whether a given modifier (such as <code>&gt;!</code> or <code>^</code>) is present. The following line can be used to convert <em>Mods</em> to a string of neutral modifiers, such as <code>^!+#</code>:</p>
<pre>Mods := RegExReplace(Mods, "[&lt;&gt;](.)(?:&gt;\1)?", "$1")</pre>
<p>Due to split-second timing, this property may be more reliable than <a href="GetKeyState.htm">GetKeyState</a> even if it is used immediately after Input terminates, or in the <a href="#OnEnd">OnEnd</a> callback.</p>
</div>

<div class="methodShort" id="EndReason"><h2>EndReason</h2>
<p>Returns an <a href="#EndReasons">EndReason string</a> indicating how Input was terminated.</p>
<pre class="Syntax">Reason := InputHook.EndReason</pre>
<p>Returns an empty string if the Input is still in progress.</p>
</div>

<div class="methodShort" id="InProgress"><h2>InProgress</h2>
<p>Returns true if the Input is in progress and false otherwise.</p>
<pre class="Syntax">Boolean := InputHook.InProgress</pre>
</div>

<div class="methodShort" id="Input"><h2>Input</h2>
<p>Returns any text collected since the last time Input was started.</p>
<pre class="Syntax">String := InputHook.Input</pre>
<p>This property can be used while the Input is in progress, or after it has ended.</p>
</div>

<div class="methodShort" id="Match"><h2>Match</h2>
<p>Returns the <em><a href="#MatchList">MatchList</a></em> item which caused the Input to terminate.</p>
<pre class="Syntax">String := InputHook.Match</pre>
<p><strong>Returns</strong> the matched item with its original case, which may differ from what the user typed if the <strong>C</strong> option was omitted. Returns an empty string if <a href="#EndReason">EndReason</a> is not "Match".</p>
</div>

<div class="methodShort" id="OnEnd"><h2>OnEnd</h2>
<p>Retrieves or sets the <a href="../objects/Functor.htm">function object</a> which is called when Input is terminated.</p>
<pre class="Syntax">MyFunc := InputHook.OnEnd</pre>
<pre class="Syntax">InputHook.OnEnd := MyFunc</pre>
<p>Type: <a href="../objects/Functor.htm">function object</a> or <a href="../Concepts.htm#nothing">empty string</a>. Default: empty string.</p>
<p>The function is passed one parameter: a reference to the InputHook object.</p>
<p>The function is called as a new <a href="../misc/Threads.htm">thread</a>, so starts off fresh with the default values for settings such as <a href="SendMode.htm">SendMode</a> and <a href="DetectHiddenWindows.htm">DetectHiddenWindows</a>.</p>
</div>

<div class="methodShort" id="OnChar"><h2>OnChar</h2>
<p>Retrieves or sets the <a href="../objects/Functor.htm">function object</a> which is called after a character is added to the input buffer.</p>
<pre class="Syntax">MyFunc := InputHook.OnChar</pre>
<pre class="Syntax">InputHook.OnChar := MyFunc</pre>
<p>Type: <a href="../objects/Functor.htm">function object</a> or <a href="../Concepts.htm#nothing">empty string</a>. Default: empty string.</p>
<p>The function is passed the following parameters: <code>InputHook, Char</code>. <em>Char</em> is a string containing the character or characters.</p>
<p>The presence of multiple characters indicates that a dead key was used prior to the last keypress, but the two keys could not be transliterated to a single character. For example, on some keyboard layouts <kbd>`</kbd><kbd>e</kbd> produces <code>è</code> while <kbd>`</kbd><kbd>z</kbd> produces <code>`z</code>.</p>
<p>The function is never called when an end key is pressed.</p>
</div>

<div class="methodShort" id="OnKeyDown"><h2>OnKeyDown</h2>
<p>Retrieves or sets the <a href="../objects/Functor.htm">function object</a> which is called when a notification-enabled key is pressed.</p>
<pre class="Syntax">MyFunc := InputHook.OnKeyDown</pre>
<pre class="Syntax">InputHook.OnKeyDown := MyFunc</pre>
<p>Type: <a href="../objects/Functor.htm">function object</a> or <a href="../Concepts.htm#nothing">empty string</a>. Default: empty string.</p>
<p>Key-down notifications must first be enabled by <a href="#KeyOpt">KeyOpt</a> or <a href="#NotifyNonText">NotifyNonText</a>.</p>
<p>The function is passed the following parameters: <code>InputHook, VK, SC</code>. <em>VK</em> and <em>SC</em> are integers. To retrieve the key name (if any), use <code>GetKeyName(Format("vk{:x}sc{:x}", VK, SC))</code>.</p>
<p>The function is called as a new <a href="../misc/Threads.htm">thread</a>, so starts off fresh with the default values for settings such as <a href="SendMode.htm">SendMode</a> and <a href="DetectHiddenWindows.htm">DetectHiddenWindows</a>.</p>
<p>The function is never called when an end key is pressed.</p>
</div>

<div class="methodShort" id="OnKeyUp"><h2>OnKeyUp <span class="ver">[v1.1.32+]</span></h2>
<p>Retrieves or sets the <a href="../objects/Functor.htm">function object</a> which is called when a notification-enabled key is released.</p>
<pre class="Syntax">MyFunc := InputHook.OnKeyUp</pre>
<pre class="Syntax">InputHook.OnKeyUp := MyFunc</pre>
<p>Type: <a href="../objects/Functor.htm">function object</a> or <a href="../Concepts.htm#nothing">empty string</a>. Default: empty string.</p>
<p>Key-up notifications must first be enabled by <a href="#KeyOpt">KeyOpt</a> or <a href="#NotifyNonText">NotifyNonText</a>. Whether a key is considered text or non-text is determined when the key is pressed. If an InputHook detects a key-up without having detected key-down, it is considered non-text.</p>
<p>The function is passed the following parameters: <code>InputHook, VK, SC</code>. <em>VK</em> and <em>SC</em> are integers. To retrieve the key name (if any), use <code>GetKeyName(Format("vk{:x}sc{:x}", VK, SC))</code>.</p>
<p>The function is called as a new <a href="../misc/Threads.htm">thread</a>, so starts off fresh with the default values for settings such as <a href="SendMode.htm">SendMode</a> and <a href="DetectHiddenWindows.htm">DetectHiddenWindows</a>.</p>
</div>

<div class="methodShort" id="BackspaceIsUndo"><h2>BackspaceIsUndo</h2>
<p>Controls whether <kbd>Backspace</kbd> removes the most recently pressed character from the end of the Input buffer.</p>
<pre class="Syntax">Boolean := InputHook.BackspaceIsUndo</pre>
<pre class="Syntax">InputHook.BackspaceIsUndo := Boolean</pre>
<p>Type: <a href="../Concepts.htm#boolean">Integer (boolean)</a>. Default: true. Option <strong>B</strong> sets the value to false.</p>
<p>When <kbd>Backspace</kbd> acts as undo, it is treated as a text entry key. Specifically, whether the key is suppressed depends on <a href="#VisibleText">VisibleText</a> rather than <a href="#VisibleNonText">VisibleNonText</a>.</p>
<p><kbd>Backspace</kbd> is always ignored if pressed in combination with a modifier key such as <kbd>Ctrl</kbd> (the logical modifier state is checked rather than the physical state).</p>
<p class="warning"><strong>Note:</strong> If the input text is visible (such as in an editor) and the arrow keys or other means are used to navigate within it, <kbd>Backspace</kbd> will still remove the last character rather than the one behind the caret (insertion point).</p>
</div>

<div class="methodShort" id="CaseSensitive"><h2>CaseSensitive</h2>
<p>Controls whether <em>MatchList</em> is case sensitive.</p>
<pre class="Syntax">Boolean := InputHook.CaseSensitive</pre>
<pre class="Syntax">InputHook.CaseSensitive := Boolean</pre>
<p>Type: <a href="../Concepts.htm#boolean">Integer (boolean)</a>. Default: false. Option <strong>C</strong> sets the value to true.</p>
</div>

<div class="methodShort" id="FindAnywhere"><h2>FindAnywhere</h2>
<p>Controls whether each match can be a substring of the input text.</p>
<pre class="Syntax">Boolean := InputHook.FindAnywhere</pre>
<pre class="Syntax">InputHook.FindAnywhere := Boolean</pre>
<p>Type: <a href="../Concepts.htm#boolean">Integer (boolean)</a>. Default: false. Option <strong>*</strong> sets the value to true.</p>
<p>If true, a match can be found anywhere within what the user types (the match can be a substring of the input text). If false, the entirety of what the user types must match one of the <em>MatchList</em> phrases. In both cases, one of the <em>MatchList</em> phrases must be typed in full.</p>
</div>

<div class="methodShort" id="MinSendLevel"><h2>MinSendLevel</h2>
<p>Retrieves or sets the minimum <a href="SendLevel.htm">send level</a> of input to collect.</p>
<pre class="Syntax">Level := InputHook.MinSendLevel</pre>
<pre class="Syntax">InputHook.MinSendLevel := Level</pre>
<p>Type: <a href="../Concepts.htm#numbers">Integer</a>. Default: 0. Option <strong>I</strong> sets the value to 1 (or a given value).</p>
<p><em>Level</em> should be an integer between 0 and 101. Events which have a send level <em>lower</em> than this value are ignored. For example, a value of 101 causes all input generated by <a href="Send.htm">SendEvent</a> to be ignored, while a value of 1 only ignores input at the default send level (zero).</p>
<p>The <a href="Send.htm#SendInput">SendInput</a> and <a href="Send.htm#SendPlay">SendPlay</a> methods are always ignored, regardless of this setting. Input generated by any source other than AutoHotkey is never ignored as a result of this setting.</p>
</div>

<div class="methodShort" id="NotifyNonText"><h2>NotifyNonText</h2>
<p>Controls whether the <a href="#OnKeyDown">OnKeyDown</a> and <a href="#OnKeyUp">OnKeyUp</a> callbacks are called whenever a non-text key is pressed.</p>
<pre class="Syntax">Boolean := InputHook.NotifyNonText</pre>
<pre class="Syntax">InputHook.NotifyNonText := Boolean</pre>
<p>Type: <a href="../Concepts.htm#boolean">Integer (boolean)</a>. Default: false.</p>
<p>Setting this to true enables notifications for all keypresses which do not produce text, such as when pressing <kbd>Left</kbd> or <kbd>Alt</kbd>+<kbd>F</kbd>. Setting this property does not affect a key's <a href="#KeyOpt">options</a>, since the production of text depends on the active window's keyboard layout at the time the key is pressed. </p>
<p>NotifyNonText is applied to key-up events by considering whether a previous key-down with a matching VK code was classified as text or non-text. For example, if NotifyNonText is true, pressing <kbd>Ctrl</kbd>+<kbd>A</kbd> will produce <a href="#OnKeyDown">OnKeyDown</a> and <a href="#OnKeyUp">OnKeyUp</a> calls for both <kbd>Ctrl</kbd> and <kbd>A</kbd>, while pressing <kbd>A</kbd> on its own will not call OnKeyDown or OnKeyUp unless <a href="#KeyOpt">KeyOpt</a> has been used to enable notifications for that key.</p>
<p>See <a href="#VisibleText">VisibleText</a> for details about which keys are counted as producing text.</p>
</div>

<div class="methodShort" id="Timeout"><h2>Timeout</h2>
<p>Retrieves or sets the timeout value in seconds.</p>
<pre class="Syntax">Seconds := InputHook.Timeout</pre>
<pre class="Syntax">InputHook.Timeout := Seconds</pre>
<p>Type: <a href="../Concepts.htm#numbers">Float</a>. Default: 0.0 (none). Option <strong>T</strong> also sets the timeout value.</p>
<p>The timeout period ordinarily starts when <a href="#Start">Start</a> is called, but will restart if this property is assigned a value while Input is in progress. If Input is still in progress when the timeout period elapses, it is terminated and <a href="#EndReason">EndReason</a> is set to the word Timeout.</p>
</div>

<div class="methodShort" id="VisibleNonText"><h2>VisibleNonText</h2>
<p>Controls whether keys or key combinations which do not produce text are visible (not blocked).</p>
<pre class="Syntax">Boolean := InputHook.VisibleNonText</pre>
<pre class="Syntax">InputHook.VisibleNonText := Boolean</pre>
<p>Type: <a href="../Concepts.htm#boolean">Integer (boolean)</a>. Default: true. Option <strong>V</strong> sets the value to true.</p>
<p>If true, keys and key combinations which do not produce text may trigger hotkeys or be passed on to the active window. If false, they are blocked.</p>
<p>See <a href="#VisibleText">VisibleText</a> for details about which keys are counted as producing text.</p>
</div>

<div class="methodShort" id="VisibleText"><h2>VisibleText</h2>
<p>Controls whether keys or key combinations which produce text are visible (not blocked).</p>
<pre class="Syntax">Boolean := InputHook.VisibleText</pre>
<pre class="Syntax">InputHook.VisibleText := Boolean</pre>
<p>Type: <a href="../Concepts.htm#boolean">Integer (boolean)</a>. Default: false. Option <strong>V</strong> sets the value to true.</p>
<p>If true, keys and key combinations which produce text may trigger hotkeys or be passed on to the active window. If false, they are blocked.</p>
<p>Any keystrokes which cause text to be appended to the Input buffer are counted as producing text, even if they do not normally do so in other applications. For instance, <kbd>Ctrl</kbd>+<kbd>A</kbd> produces text if the <a href="#option-m"><strong>M</strong> option</a> is used, and <kbd>Escape</kbd> produces the control character <code>Chr(27)</code>.</p>
<p>Dead keys are counted as producing text, although they do not typically produce an immediate effect. Pressing a dead key might also cause the following key to produce text (if only the dead key's character).</p>
<p><kbd>Backspace</kbd> is counted as producing text only when it <a href="#BackspaceIsUndo">acts as undo</a>.</p>
<p>The <a href="../KeyList.htm#modifier">standard modifier keys</a> and CapsLock, NumLock and ScrollLock are always visible (not blocked).</p>
</div>

<h2 id="EndReasons">EndReason</h2>
<p>The EndReason property returns one of the following strings:</p>
<table class="info">
  <tr>
    <td>Stopped</td>
    <td>The Stop method was called or Start has not yet been called for the first time.</td>
  </tr>
  <tr>
    <td>Max</td>
    <td>The Input reached the maximum allowed length and it does not match any of the items in <em>MatchList</em>.</td>
  </tr>
  <tr>
    <td>Timeout</td>
    <td>The Input timed out.</td>
  </tr>
  <tr>
    <td>Match</td>
    <td>The Input matches one of the items in <em>MatchList</em>. The <a href="#Match">Match</a> property contains the matched item.</td>
  </tr>
  <tr>
    <td>EndKey</td>
    <td>
      <p>One of the <em>EndKeys</em> was pressed to terminate the Input. The <a href="#EndKey">EndKey</a> property contains the terminating key name or character without braces.</p>
    </td>
  </tr>
  <tr>
    <td></td>
    <td>If the Input is in progress, EndReason is blank.</td>
  </tr>
</table>

<h2 id="Remarks">Remarks</h2>
<p>The <a href="#Start">Start</a> method must be called before input will be collected.</p>
<p>InputHook is designed to allow different parts of the script to monitor input, with minimal conflicts. It can operate continuously, such as to watch for <a href="#ExSac">arbitrary words</a> or other patterns. It can also operate temporarily, such as to collect user input or temporarily override specific (or <a href="#ExKeyWaitAny">non-specific</a>) keys without interfering with hotkeys.</p>
<p>Keyboard <a href="../Hotkeys.htm">hotkeys</a> are still in effect while an Input is in progress, but cannot be triggered by keys which the Input suppresses.</p>
<p>Keys are either suppressed (blocked) or not depending on the following factors (in order):</p>
<ul>
  <li>If the <a href="#KeyOpt-v">V option</a> is in effect for this VK or SC, it is not suppressed.</li>
  <li>If the <a href="#KeyOpt-s">S option</a> is in effect for this VK or SC, it is suppressed.</li>
  <li>If the key is a <a href="../KeyList.htm#modifier">standard modifier key</a> or CapsLock, NumLock or ScrollLock, it is not suppressed.</li>
  <li><a href="#VisibleText">VisibleText</a> or <a href="#VisibleNonText">VisibleNonText</a> is consulted, depending on whether the key produces text. If the property is false, the key is suppressed.   See <a href="#VisibleText">VisibleText</a> for details about which keys are counted as producing text.</li>
</ul>
<p>The <a href="_InstallKeybdHook.htm">keyboard hook</a> is required while an Input is in progress, but will be uninstalled automatically if it is no longer needed when the Input is terminated. The presence of the keyboard hook causes the script to become temporarily <a href="_Persistent.htm">persistent</a>, meaning that <a href="ExitApp.htm">ExitApp</a> may be needed to terminate it.</p>
<p>AutoHotkey does not support Input Method Editors (IME). The keyboard hook intercepts keyboard events and translates them to text by using <a href="https://docs.microsoft.com/windows/desktop/api/winuser/nf-winuser-tounicodeex">ToUnicodeEx</a> or ToAsciiEx (except in the case of <a href="https://docs.microsoft.com/windows/desktop/inputdev/virtual-key-codes#vk_packet">VK_PACKET</a> events, which encapsulate a single character).</p>
<p>If you use multiple languages or keyboard layouts, Input uses the keyboard layout of the active window rather than the script's (regardless of whether the Input is <a href="#vis">visible</a>).</p>
<p>Although not as flexible, <a href="../Hotstrings.htm">hotstrings</a> are generally easier to use.</p>

<h2 id="comparison">InputHook vs. Input</h2>
<p>InputHook and the <a href="Input.htm">Input</a> command are two different interfaces for the same underlying functionality. The following are mostly equivalent:</p>
<pre>
Input, OutputVar, %Options%, %EndKeys%, %MatchList%
</pre><pre>
ih := InputHook(Options, EndKeys, MatchList)
ih.Start()
ErrorLevel := ih.Wait()
if (ErrorLevel = "EndKey")
    ErrorLevel .= ":" ih.EndKey
OutputVar := ih.Input
</pre>
<p>The Input command terminates any previous Input which it started, whereas InputHook allows <a href="#stack">more than one Input</a> at a time.</p>
<p><em>Options</em> is interpreted the same, but the default settings differ:</p>
<ul>
  <li>The Input command limits the length of the input to 16383, while InputHook limits it to 1023. This can be overridden with the <a href="#option-l">L option</a>, and there is no absolute maximum.</li>
  <li>The Input command blocks both text and non-text keystrokes by default, and blocks neither if the <a href="Input.htm#vis">V option</a> is present. By contrast, InputHook blocks only text keystrokes by default (<a href="#VisibleNonText">VisibleNonText</a> defaults to true), so most hotkeys can be used while an Input is in progress.</li>
</ul>
<p>The Input command blocks the <a href="../misc/Threads.htm">thread</a> while it is in progress, whereas InputHook allows the thread to continue, or even exit (which allows any thread that it interrupted to resume). Instead of waiting, the script can register an <a href="#OnEnd">OnEnd</a> function to be called when the Input is terminated.</p>
<p>The Input command returns the user's input only after the Input is terminated, whereas InputHook's <a href="Input.htm">Input</a> property allows it to be retrieved at any time. The script can register an <a href="#OnChar">OnChar</a> function to be called whenever a character is added, instead of continuously checking the Input property.</p>
<p>InputHook gives much more control over individual keys via the <a href="#KeyOpt">KeyOpt</a> method. This includes adding or removing end keys, suppressing or not suppressing specific keys, or ignoring the text produced by specific keys.</p>
<p>Unlike the Input command, InputHook can be used to detect keys which do not produce text, <em>without</em> terminating the Input. This is done by registering an <a href="#OnKeyDown">OnKeyDown</a> function and using <a href="#KeyOpt">KeyOpt</a> or <a href="#NotifyNonText">NotifyNonText</a> to specify which keys are of interest.</p>
<p>If a <em>MatchList</em> item caused the Input to terminate, the <a href="#Match">Match</a> property can be consulted to determine exactly which match (this is more useful when the <a href="#asterisk">* option</a> is present).</p>
<p>Although the script can consult <a href="GetKeyState.htm">GetKeyState</a> after the Input command returns, sometimes it does not accurately reflect which keys were pressed when the Input was terminated. InputHook's <a href="#EndMods">EndMods</a> property reflects the logical state of the modifier keys at the time Input was terminated.</p>
<p>There are some differences relating to backward-compatibility:</p>
<ul>
  <li>The Input command stores end keys <kbd>A</kbd>-<kbd>Z</kbd> in uppercase even though other letters on some keyboard layouts are lowercase. Passing the value to <a href="Send.htm">Send</a> would produce a shifted keystroke instead of a plain one. By contrast, InputHook's <a href="#EndKeys">EndKeys</a> property always returns the normalized name; i.e. whichever character is produced by pressing the key without holding <kbd>Shift</kbd> or other modifiers.</li>
  <li><p>If a key name used in <em>EndKeys</em> corresponds to a VK which is shared between two physical keys (such as <kbd>NumpadUp</kbd> and <kbd>Up</kbd>), the Input command handles the primary key by VK and the secondary key by SC, whereas InputHook handles both by SC. <code>{vkNN}</code> notation can be used to handle the key by VK.</p>
  <p>When the end key is handled by VK, both physical keys can terminate the Input. For example, <code>{NumpadUp}</code> would cause the Input command to be terminated by pressing <kbd>Up</kbd>, but ErrorLevel would contain <code>EndKey:NumpadUp</code> since only the VK is considered.</p>
  <p>When an end key is handled by SC, the Input command always produces names for the known secondary SC of any given VK, and always produces <code>sc<i>NNN</i></code> for any other key (even if it has a name). By contrast, InputHook produces a name if the key has one.</p></li>
</ul>

<h2>Related</h2>
<p><a href="Input.htm">Input</a>, <a href="KeyWait.htm">KeyWait</a>, <a href="../Hotstrings.htm">Hotstrings</a>, <a href="InputBox.htm">InputBox</a>, <a href="_InstallKeybdHook.htm">#InstallKeybdHook</a>, <a href="../misc/Threads.htm">Threads</a>, <a href="IfIn.htm">if var in/contains MatchList</a></p>

<h2>Examples</h2>
<div class="ex" id="ExKeyWaitAny">
<p><a href="#ExKeyWaitAny">#1</a>: Wait for the user to press any single key.</p>
<pre>
MsgBox % KeyWaitAny()

<em>; Same again, but don't block the key.</em>
MsgBox % KeyWaitAny("V")

KeyWaitAny(Options:="")
{
    ih := InputHook(Options)
    ih.KeyOpt("{All}", "ES")  <em>; End and Suppress</em>
    ih.Start()
    ErrorLevel := ih.Wait()  <em>; Store EndReason in ErrorLevel</em>
    return ih.EndKey  <em>; Return the key name</em>
}
</pre>
</div>
<div class="ex" id="ExKeyWaitCombo">
<p><a href="#ExKeyWaitCombo">#2</a>: Wait for any key in combination with Ctrl/Alt/Shift/Win.</p>
<pre>
MsgBox % KeyWaitCombo()

KeyWaitCombo(Options:="")
{
    ih := InputHook(Options)
    ih.KeyOpt("{All}", "ES")  <em>; End and Suppress</em>
    <em>; Exclude the modifiers</em>
    ih.KeyOpt("{LCtrl}{RCtrl}{LAlt}{RAlt}{LShift}{RShift}{LWin}{RWin}", "-ES")
    ih.Start()
    ErrorLevel := ih.Wait()  <em>; Store EndReason in ErrorLevel</em>
    return ih.EndMods . ih.EndKey  <em>; Return a string like &lt;^&lt;+Esc</em>
}
</pre>
</div>
<div class="ex" id="ExSac">
<p><a href="#ExSac">#3</a>: Simple auto-complete: any day of the week.  Pun aside, this is a fully functional example.  Simply run the script and start typing today, press <kbd>Tab</kbd> to complete or press <kbd>Escape</kbd> to exit.</p>
<pre>global WordList := "Monday`nTuesday`nWednesday`nThursday`nFriday`nSaturday`nSunday"

global Suffix := "", SacHook

SacHook := InputHook("V", "{Esc}")
SacHook.OnChar := Func("SacChar")
SacHook.OnKeyDown := Func("SacKeyDown")
SacHook.OnEnd := Func("SacEnd")
SacHook.KeyOpt("{Backspace}", "N")
SacHook.Start()

SacChar(ih, char)  <em>; Called when a character is added to SacHook.Input.</em>
{
    Suffix := ""
    if RegExMatch(ih.Input, "`nm)\w+$", prefix)
        RegExMatch(WordList, "`nmi)^" prefix "\K.*", Suffix)
    
    ToolTip % Suffix, % A_CaretX + 15, % A_CaretY    
    
    <em>; Intercept Tab only while we're showing a Tooltip.</em>
    ih.KeyOpt("{Tab}", Suffix = "" ? "-NS" : "+NS")
}

SacKeyDown(ih, vk, sc)
{
    if (vk = 8) <em>; Backspace</em>
        SacChar(ih, "")
    else if (vk = 9) <em>; Tab</em>
        Send % "{Text}" Suffix
}

SacEnd()
{
    ExitApp
}
</pre>
</div>

</body>
</html>
